package org.zachary.agent.infrastructure.config;


import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import org.zachary.agent.infrastructure.filter.JwtAuthFilter;
import org.zachary.agent.infrastructure.service.UserDetailServiceImpl;

import java.util.List;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
    @Resource
    private UserDetailServiceImpl userDetailService;

    // 密码编码器（保留）
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 认证提供者（保留）
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setPasswordEncoder(passwordEncoder());
        authProvider.setUserDetailsService(userDetailService);
        return authProvider;
    }

    // 认证管理器（保留）
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
        System.out.println("认证管理器");
        return configuration.getAuthenticationManager();
    }

    // 安全过滤器链（重点重构）
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        System.out.println("安全过滤器");
        return http
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/user/login", "/user/register","/user/refresh","/user/admin/login","/user/credit/score").permitAll()
                        .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/doc.html").permitAll()
                        .requestMatchers("/admin/**").hasRole("admin")
                        .anyRequest().authenticated()
                )
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 启用无状态会话
                )
                .authenticationProvider(authenticationProvider())
                .exceptionHandling(ex -> ex
                        .authenticationEntryPoint(jwtAuthEntryPoint()) // JWT认证入口
                        .accessDeniedHandler(accessDeniedHandler()) // 自定义权限拒绝
                )
                .csrf(AbstractHttpConfigurer::disable) // 禁用CSRF
                .cors(Customizer.withDefaults()) // 启用CORS
                .addFilterBefore(jwtAuthFilter(), UsernamePasswordAuthenticationFilter.class) // JWT过滤器
                .build();
    }

    // JWT认证过滤器
    @Bean
    public JwtAuthFilter jwtAuthFilter() {
        return new JwtAuthFilter();
    }

    // JWT认证异常处理器
    @Bean
    public AuthenticationEntryPoint jwtAuthEntryPoint() {
        System.out.println("JWT认证处理器");
        return (request, response, authException) ->
                response.sendError(HttpStatus.UNAUTHORIZED.value(), "无效凭证");
    }

    // 权限拒绝处理器
    @Bean
    public AccessDeniedHandler accessDeniedHandler() {

        return (request, response, accessDeniedException) ->
                response.sendError(HttpStatus.FORBIDDEN.value(), "权限不足");
    }
}
